home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / FLGTST20.ZIP;1 / FLAGTEST.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1994-03-27  |  6.7 KB  |  294 lines

  1. Program FlagTest;  { Generates a comlete report of Intel CPU flag behavior }
  2.                    { Version 2.0· Last modified  27-03-94 }
  3.  
  4. Uses CRT,DOS;
  5.  
  6. CONST
  7.  StartCount =   -4;
  8.    EndCount =   10;
  9.  
  10.    Normcol=$07; {normal}
  11.    Flipcol=$70; {inverse}
  12.     Setcol=$0C; {bright red}
  13.   Clearcol=$02; {green}
  14.   Stillcol=$09; {bright blue}
  15.     Lowcol=$06; {brown}
  16.  
  17. VAR
  18.     Count:integer;
  19.     Tmpflag:byte;
  20.  
  21.  
  22. {  TestRoutine contains the actual instruction(s) to be analyzed. }
  23. {  On entry,  AX=BX=CX=DX=SI=DI == 0   }
  24.  
  25. Procedure TestRoutine;Assembler;
  26. ASM
  27.  
  28.   CMC               { This is just a weird combination     }
  29.   MOV CX,COUNT      { to demonstrate all possible outcomes }
  30.   SHL CL,CL         { of the FlagTest analysis.            }
  31.  
  32. END;
  33.  
  34.  
  35.  
  36.  
  37.  
  38. Procedure CallTest;Assembler;
  39. ASM
  40.    PUSH SI
  41.    PUSHF   {flags and SI are preserved}
  42.  
  43.    PUSHF
  44.    POP  AX
  45.  
  46.    AND AX,BX   { clear flags - AND mask in BX }
  47.    OR  AX,DX   { set   flags - OR  mask in CX }
  48.  
  49.    PUSH AX
  50.     XOR AX,AX
  51.     XOR BX,BX
  52.     XOR DX,DX
  53.     XOR SI,SI
  54.     XOR DI,DI
  55.    POPF      { install our preset flags }
  56.    Call TestRoutine
  57.  
  58.    PUSHF
  59.    POP AX    { flags output to AX }
  60.  
  61.   POPF
  62.   POP SI
  63. END;{CallTest}
  64.  
  65.  
  66.  
  67.  
  68. Function TestFlag(Fbit:byte):byte;   { output = 0/1/2/3 }
  69. BEGIN
  70. ASM
  71.  
  72.   {
  73.    For precise flag behavior measurement, we test the situation
  74.    where all other inputs (registers and flags) are zero.
  75.    the testroutine is then called twice, once with the flag set
  76.    and once with it cleared, to be able to detect cases where
  77.    it is flipped or unaffected by the instruction(s) in TestRoutine.
  78.    }
  79.  
  80.  MOV TMPFLAG,0
  81.  
  82.  MOV SI,1
  83.  MOV CL,Fbit
  84.  SHL SI,CL         { SI now has bit Fbit set }
  85.  
  86.  
  87.  MOV BX,$E32A      { the AND mask - must set all flags to 0 }
  88.                    { but not touch undefined or system flags }
  89.  MOV DX,$0000      { the OR mask }
  90.                    { we enter the first test with all flags cleared }
  91.  
  92.   XOR CX,CX
  93.   Call CallTest  { output in AX }
  94.   AND  AX,SI     { isolate flag we're looking for }
  95.  JZ @ov1
  96.   OR TMPFLAG,1   { note result in bit 0 of output }
  97.  @ov1:
  98.  
  99.  
  100.  MOV BX,$E32A { the AND mask }
  101.  MOV DX,SI    { DX is the OR mask }
  102.               { we enter the the second test with bit(Fbit) SET }
  103.  
  104.   XOR CX,CX
  105.   Call CallTest  { output in AX }
  106.   AND  AX,SI     { isolate flag we're looking for }
  107.  JZ @ov2
  108.   OR TMPFLAG,2   { note result in bit 1 of output }
  109.  @ov2:
  110.  
  111. END;{asm}
  112.  
  113.  TestFlag:=TMPflag;
  114.  
  115. END; {TestFlag}
  116.  
  117.  
  118.  
  119.  
  120. Function TestCXZ:byte;  { output = 0/1/2/3 }
  121. BEGIN
  122. ASM
  123.  
  124.  MOV TMPFLAG,0
  125.  
  126.  MOV BX,$E32A       ;  { the AND mask }
  127.  MOV DX,$0000       ;  { OR mask      }
  128.  
  129.   MOV CX,1        { start with CX = 0 condition 'CLEARED' }
  130.   Call CallTest;
  131.   OR CX,CX        { test for CX=0 condition }
  132.  JNZ @ov1
  133.   OR TMPFLAG,1  { note result in bit 0 of output }
  134.  @ov1:
  135.  
  136.  MOV BX,$E32A
  137.  MOV DX,$0000
  138.  
  139.   MOV CX,0       { start with CX = 0 condition 'SET' }
  140.   Call CallTest;
  141.   OR CX,CX       { test for CX=0 condition }
  142.  JNZ @ov2
  143.   OR TMPFLAG,2   { note result in bit 1 of output }
  144.  @ov2:
  145.  
  146. END;{asm}
  147.  
  148.  TestCXZ:=TMPflag;
  149.  
  150. END;
  151.  
  152.  
  153.  
  154. Function Illdefined(Fbit:byte):boolean;
  155. begin
  156.  Illdefined:= ( TestFlag(Fbit) in [1,2] ); { not simply SET or CLEARED }
  157. end;
  158.  
  159.  
  160.  
  161. Procedure PrintFlagBit(Fbit:byte;Fname:string);
  162.  { print Fname in colors given by flag changes }
  163. var
  164.    ChaID:byte;
  165.    Icat:string[8];
  166. begin
  167. Write(' ');
  168.  
  169.  
  170. Case Fbit of
  171.      32: chaid:= TestCXZ;
  172.      33: begin
  173.          chaid:= ((TestFlag(0)  or TestFlag(6))  xor 3);  {JA}
  174.          if Illdefined(0) or Illdefined(6) then Chaid:=4;
  175.          end;
  176.      34: begin
  177.          chaid:= ((TestFlag(7) xor TestFlag(11)) xor 3);  {JGE}
  178.          if Illdefined(7) or Illdefined(11) then Chaid:=4;
  179.          end;
  180.      35: begin
  181.          chaid:=(((TestFlag(7) xor TestFlag(11))          {JG}
  182.          or TestFlag(6)) xor 3) ;
  183.          if Illdefined(7) or Illdefined(11) or Illdefined(6) then Chaid:=4;
  184.          end;
  185.      else ChaID:=TestFlag(Fbit);
  186.     end; {case}
  187.  
  188.  
  189. Case ChaID of
  190.          0:begin Textattr:=Clearcol; Icat:=' O '; end;  { Cleared }
  191.          1:begin Textattr:= Flipcol; Icat:=' X '; end;  { Flipped }
  192.          2:begin Textattr:=Stillcol; Icat:=' U '; end;  { Unchanged }
  193.          3:begin Textattr:=  Setcol; Icat:=' 1 '; end;  { Set }
  194.          4:begin Textattr:=  Lowcol; Icat:=' - '; end;  { Undefined }
  195.         end;{case}
  196.  
  197.  Write(Fname);
  198.  
  199.  Textattr:=NormCol;
  200.  Write(Icat);
  201.  
  202. end;
  203.  
  204.  
  205.  
  206. Procedure PrintAllFlags;
  207. Begin
  208. Write('∫');               { *  These are the 'jumpable' flags }
  209. PrintFlagBit(0 ,'Carry');
  210. PrintFlagBit(6 ,'Zero');
  211. PrintFlagBit(7 ,'Sign');
  212. PrintFlagBit(11,'OF');      { Overflow }
  213. PrintFlagBit(2 ,'P');       { Parity }
  214. Write('≥');               { * The 'jumpable' cases depending on multiple flags }
  215. PrintFlagBit(33,'JA');      { Above (unsigned) }
  216. PrintFlagBit(34,'JGE');     { Greater or Equal (signed) }
  217. PrintFlagBit(35,'JG');      { Greater (signed) }
  218. Write('≥');
  219. PrintFlagBit(32,'CXZ');   { * Simply the CX=ZERO condition }
  220. Write('≥');
  221. PrintFlagBit(4 ,'Aux');   { * Not really useful but shown anyway ..}
  222.  
  223. { PrintFlagBit(10,'Dir'); }  { Wanna see the Direction flag instead }
  224.  
  225. end;
  226.  
  227.  
  228.  
  229. Function Redirected:Boolean;
  230. { detect if user wants redirectable output }
  231. Assembler;
  232. ASM
  233.    MOV   AX,04400h  { query device info }
  234.    MOV   BX,1       { for device STDOUT }
  235.    INT   021h
  236.    XOR   AX,AX
  237.    ADD   DL,DL      { bit 7 clear = STDOUT redirected as FILE OUTPUT}
  238.    CMC
  239.    ADC   AX,AX      { prepare boolean output AX=1=True }
  240. END;
  241.  
  242.  
  243.  
  244. BEGIN  { MAIN }
  245.  
  246. If  Redirected then  begin
  247.        WriteLn(' FlagTest 2.0 - writing output to file ');
  248.        { In Borland/Turbo Pascal, using CRT is needed to create }
  249.        { color in text output; however this bypasses DOS so the }
  250.        { output is not redirectable. Here we reroute the output }
  251.        { to the official DOS STDOUT device again.               }
  252.        ASSIGN(Output,'');  { Put pascal output back on real STDOUT.. }
  253.        REWRITE(Output);    { Open for writing }
  254.      end;
  255.  
  256. WriteLn;
  257. WriteLn('FlagTest 2.0·   (C) Copyright 1994 by Erik de Neve');
  258. WriteLn;
  259. WriteLn('  Tested:  CMC / MOV CX,(Input) / SHL CL,CL');
  260. WriteLn;
  261.  
  262. Textattr:=NormCol;
  263. Write('Input ∫ Flags: ');
  264.  
  265.  Textattr:=setcol;
  266.  Write(' 1: set ');
  267.  
  268.  Textattr:=clearcol;
  269.  Write(' O: cleared ');
  270.  
  271.  Textattr:=stillcol;
  272.  Write(' U: unchanged ');
  273.  
  274.  Textattr:=flipcol;
  275.  Write(' X: flipped ');
  276.  
  277.  Textattr:=lowcol;
  278.  Write(' -: undefined ');
  279.  
  280.  Textattr:=NormCol;
  281.  
  282. WriteLn;
  283. WriteLn('ƒƒƒƒƒƒ◊ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒ');
  284.  
  285. For Count:= startcount to endcount do
  286.   BEGIN
  287.    Write(Count:6);
  288.    PrintAllFlags;
  289.    WriteLn;
  290.   END;
  291.  
  292. END.
  293.  
  294.